package com.stanwind.netty.api;

import com.stanwind.netty.constant.CardType;
import com.stanwind.netty.domain.pojo.Card;
import com.stanwind.netty.domain.pojo.CardTypeIndex;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by StanWind on 2017/2/22.
 */
@Component
public class CardUtils {
    /**
     * 获取牌型
     * @param myCards 手牌
     * @return
     */
    public static CardType getCardType(List<Card> myCards){
        return  GetCardType(convertToWeightList(myCards));
    }

    /**
     * 判断我选择出的牌和上家的牌的大小，决定是否可以出牌
     *
     * @param myCards  我的牌
     * @param prevCards 上家出牌
     * @return
     */
    public static boolean isOvercomePrev(List<Card> myCards, List<Card> prevCards) {
        List<Integer> a = convertToWeightList(myCards);
        List<Integer> b = convertToWeightList(prevCards);
        return isOvercomePrev(a, GetCardType(a), b, GetCardType(b));
    }

    /**
     * 判断手牌要不要得起
     * @param myCards   我的手牌
     * @param prevCards 上家出牌
     * @return
     */
    public static boolean isOvercomePrevHint(List<Card> myCards, List<Card> prevCards) {
        List<Integer> a = convertToWeightList(myCards);
        List<Integer> b = convertToWeightList(prevCards);
        return isOvercomePrevHint(a, b, GetCardType(b));
    }

    /**
     * 获取牌型
     *
     * @param myCards 权值
     * @return 牌型
     */
    private static CardType GetCardType(List<Integer> myCards) {
        CardType cardType = CardType.ERROR_CARD;
        String talk = "不能出啊";
        //		CardIndexCompute (myCards);
        if (myCards != null) {
            // 大概率事件放前边，提高命中率
            if (IsDan(myCards)) {
                cardType = CardType.SINGLE_CARD;
                talk = "一张" + (myCards.get(0));
            } else if (IsDuiWang(myCards)) {
                cardType = CardType.KING_BOMB_CARD;
                talk = "王炸";
            } else if (IsDuiZi(myCards)) {
                cardType = CardType.DOUBLE_CARD;
                talk = "对" + (myCards.get(0));
            } else if (IsZhaDan(myCards)) {
                cardType = CardType.BOMB_CARD;
                talk = "炸弹!";
            } else if (IsSanDaiYi(myCards) != -1) {
                cardType = CardType.THREE_ONE_CARD;
                talk = "三带一";
            } else if (IsSanDaiEr(myCards) != -1) {
                cardType = CardType.THREE_TWO_CARD;
                talk = "三带二";
            } else if (IsSanBuDai(myCards)) {
                cardType = CardType.THREE_CARD;
                talk = "三张" + (myCards.get(0));
            } else if (IsShunZi(myCards)) {
                cardType = CardType.LIAN_CARD;
                talk = "顺子";
            } else if (IsLianDui(myCards)) {
                cardType = CardType.LIAN_DUI_CARD;
                talk = "连对";
            } else if (IsSiDaiEr(myCards)) {
                cardType = CardType.FOUR_TWO_CARD;
                talk = "四带俩单";
            } else if (IsSiDaiErDui(myCards)) {
                cardType = CardType.FOUR_TWOTWO_CARD;
                talk = "四带俩对";
            } else if (IsFeiJiBuDai(myCards)) {
                cardType = CardType.FEIJI_NO_CARD;
                talk = "飞机没翅膀";
            } else if (IsFeiJiDaiDan(myCards)) {
                cardType = CardType.FEIJI_SINGLE_CARD;
                talk = "飞机单翅膀";
            } else if (IsFeiJiDaiDui(myCards)) {
                cardType = CardType.FEIJI_DOUBLE_CARD;
                talk = "飞机双翅膀！";
            }

        }
        //System.err.println(talk);
        return cardType;
    }


    /**
     * 将listcard转为list int
     * @return
     */
    private static List<Integer> convertToWeightList(List<Card> cards){
        List<Integer> integers = new ArrayList<>();
        for(Card card:cards)
            integers.add(card.getWeight().getValue());
        return integers;
    }



    /**
     * 判断我选择出的牌和上家的牌的大小，决定是否可以出牌
     *
     * @param myCards      我的牌
     * @param myCardType   手牌类型
     * @param prevCards
     * @param prevCardType
     * @return
     */
    private static boolean isOvercomePrev(List<Integer> myCards,
                                          CardType myCardType, List<Integer> prevCards, CardType prevCardType) {
        // 我的牌和上家的牌都不能为null
        if (myCards == null || prevCards == null) {
            return false;
        }

        if (myCardType == null || prevCardType == CardType.ERROR_CARD) {
            System.out.println("上家出的牌不合法，所以不能出。");
            return false;
        }

        // 上一手牌的个数
        int prevSize = prevCards.size();
        int mySize = myCards.size();

        // 我先出牌，上家没有牌
        if (prevSize == 0 && mySize != 0) {
            return true;
        }

        // 集中判断是否王炸，免得多次判断王炸
        if (prevCardType == CardType.KING_BOMB_CARD) {
            //System.out.println("上家王炸，肯定不能出。");
            return false;
        } else if (myCardType == CardType.KING_BOMB_CARD) {
            //System.out.println("我王炸，肯定能出。");
            return true;
        }

        // 集中判断对方不是炸弹，我出炸弹的情况
        if (prevCardType != CardType.BOMB_CARD && myCardType == CardType.BOMB_CARD) {
            return true;
        }

        // 默认情况：上家和自己想出的牌都符合规则
        SortCards(myCards);// 对牌排序
        SortCards(prevCards);// 对牌排序

        int myGrade = myCards.get(0);
        int prevGrade = prevCards.get(0);

        // 比较2家的牌，主要有2种情况，1.我出和上家一种类型的牌，即对子管对子；
        // 2.我出炸弹，此时，和上家的牌的类型可能不同
        // 王炸的情况已经排除

        // 单
        if (prevCardType == CardType.SINGLE_CARD && myCardType == CardType.SINGLE_CARD) {
            // 一张牌可以大过上家的牌
            return CompareGrade(myGrade, prevGrade);
        }
        // 对子


        else if (prevCardType == CardType.DOUBLE_CARD
                && myCardType == CardType.DOUBLE_CARD) {
            // 2张牌可以大过上家的牌
            return CompareGrade(myGrade, prevGrade);

        }
        // 3不带
        else if (prevCardType == CardType.THREE_CARD
                && myCardType == CardType.THREE_CARD) {
            // 3张牌可以大过上家的牌
            return CompareGrade(myGrade, prevGrade);
        }
        // 炸弹
        else if (prevCardType == CardType.BOMB_CARD
                && myCardType == CardType.BOMB_CARD) {
            // 4张牌可以大过上家的牌
            return CompareGrade(myGrade, prevGrade);

        }
        // 3带1
        else if (prevCardType == CardType.THREE_ONE_CARD
                && myCardType == CardType.THREE_ONE_CARD) {
            //------------------------------------------------???第二张???
            // 3带1只需比较第2张牌的大小
            myGrade = myCards.get(1);
            prevGrade = prevCards.get(1);
            return CompareGrade(myGrade, prevGrade);

        }
        // 3带2
        else if (prevCardType == CardType.THREE_TWO_CARD
                && myCardType == CardType.THREE_TWO_CARD) {
            //------------------------------------------------???第二张???
            // 3带2只需比较第3张牌的大小
            myGrade = myCards.get(2);
            prevGrade = prevCards.get(2);
            return CompareGrade(myGrade, prevGrade);

        }
        // 4带2
        else if (prevCardType == CardType.FOUR_TWO_CARD
                && myCardType == CardType.FOUR_TWO_CARD) {

            // 4带2只需比较第3张牌的大小
            myGrade = myCards.get(2);
            prevGrade = prevCards.get(2);
            return CompareGrade(myGrade, prevGrade);
        }
        // 4带2对
        else if (prevCardType == CardType.FOUR_TWOTWO_CARD
                && myCardType == CardType.FOUR_TWOTWO_CARD) {
            CardTypeIndex carT_index_my = CardIndexCompute(myCards);
            CardTypeIndex carT_index_pre = CardIndexCompute(prevCards);
            return CompareGrade(carT_index_my.four_index.get(0), carT_index_pre.four_index.get(0));
        }
        // 顺子
        else if (prevCardType == CardType.LIAN_CARD
                && myCardType == CardType.LIAN_CARD) {
            if (mySize != prevSize) {
                return false;
            } else {
                // 顺子只需比较最大的1张牌的大小
                myGrade = myCards.get(mySize - 1);
                prevGrade = prevCards.get(prevSize - 1);
                return CompareGrade(myGrade, prevGrade);
            }

        }
        // 连对
        else if (prevCardType == CardType.LIAN_DUI_CARD
                && myCardType == CardType.LIAN_DUI_CARD) {
            if (mySize != prevSize) {
                return false;
            } else {
                // 连对只需比较最大的1张牌的大小
                myGrade = myCards.get(mySize - 1);
                prevGrade = prevCards.get(prevSize - 1);
                return CompareGrade(myGrade, prevGrade);
            }

        }
        // 飞机不带
        else if (prevCardType == CardType.FEIJI_NO_CARD
                && myCardType == CardType.FEIJI_NO_CARD) {
            if (mySize != prevSize) {
                return false;
            } else {
                // 飞机只需比较第5张牌的大小(特殊情况333444555666没有考虑，即12张的飞机，可以有2种出法)
                myGrade = myCards.get(4);
                prevGrade = prevCards.get(4);
                return CompareGrade(myGrade, prevGrade);
            }
        }
        // 飞机带单
        else if (prevCardType == CardType.FEIJI_SINGLE_CARD
                && myCardType == CardType.FEIJI_SINGLE_CARD) {
            if (mySize != prevSize) {
                return false;
            } else {
                // 飞机只需比较第5张牌的大小(特殊情况333444555666没有考虑，即12张的飞机，可以有2种出法)
                myGrade = myCards.get(4);
                prevGrade = prevCards.get(4);
                return CompareGrade(myGrade, prevGrade);
            }
        }
        // 飞机带对
        else if (prevCardType == CardType.FEIJI_DOUBLE_CARD
                && myCardType == CardType.FEIJI_DOUBLE_CARD) {
            if (mySize != prevSize) {
                return false;
            } else {
                // 飞机只需比较第5张牌的大小(特殊情况333444555666没有考虑，即12张的飞机，可以有2种出法)
                myGrade = myCards.get(4);
                prevGrade = prevCards.get(4);
                return CompareGrade(myGrade, prevGrade);
            }
        }
        // 默认不能出牌
        return false;
    }


    /**
     * 判断手牌要不要得起
     *
     * @param myCards      手牌权值
     * @param prevCards    上家牌
     * @param prevCardType 上家牌型
     * @return
     */
    private static boolean isOvercomePrevHint(List<Integer> myCards,
                                              List<Integer> prevCards, CardType prevCardType) {
        // 我的牌和上家的牌都不能为null
        if (myCards == null || prevCards == null) {
            return false;
        }

        if (prevCardType == null) {
            System.out.println("上家出的牌不合法，所以不能出。");
            return false;
        }

        // 默认情况：上家和自己想出的牌都符合规则
        SortCards(myCards);// 对牌排序
        SortCards(prevCards);// 对牌排序

        // 上一首牌的个数
        int prevSize = prevCards.size();
        int mySize = myCards.size();

        // 我先出牌，上家没有牌
        if (prevSize == 0 && mySize != 0) {
            return true;
        }

        // 集中判断是否王炸，免得多次判断王炸
        if (prevCardType == CardType.KING_BOMB_CARD) {
            System.out.println("上家王炸，肯定不能出。");
            return false;
        }

        if (mySize >= 2) {
            List<Integer> cards = new ArrayList<>();
            cards.add(myCards.get(mySize - 1));
            cards.add(myCards.get(mySize - 2));
            if (IsDuiWang(cards)) {
                return true;
            }
        }

        // 集中判断对方不是炸弹，我出炸弹的情况
        if (prevCardType != CardType.BOMB_CARD) {
            if (mySize < 4) {
                return false;
            } else {
                for (int i = 0; i < mySize - 3; i++) {
                    int grade0 = myCards.get(i);
                    int grade1 = myCards.get(i + 1);
                    int grade2 = myCards.get(i + 2);
                    int grade3 = myCards.get(i + 3);

                    if (grade1 == grade0 && grade2 == grade0
                            && grade3 == grade0) {
                        return true;
                    }
                }
            }

        }

        int prevGrade = prevCards.get(0);

        // 比较2家的牌，主要有2种情况，1.我出和上家一种类型的牌，即对子管对子；
        // 2.我出炸弹，此时，和上家的牌的类型可能不同
        // 王炸的情况已经排除

        // 上家出单
        if (prevCardType == CardType.SINGLE_CARD) {
            // 一张牌可以大过上家的牌
            for (int i = mySize - 1; i >= 0; i--) {
                int grade = myCards.get(i);
                if (grade > prevGrade) {
                    // 只要有1张牌可以大过上家，则返回true
                    return true;
                }
            }

        }
        // 上家出对子
        else if (prevCardType == CardType.DOUBLE_CARD) {
            // 2张牌可以大过上家的牌
            for (int i = mySize - 1; i >= 1; i--) {
                int grade0 = myCards.get(i);
                int grade1 = myCards.get(i - 1);

                if (grade0 == grade1) {
                    if (grade0 > prevGrade) {
                        // 只要有1对牌可以大过上家，则返回true
                        return true;
                    }
                }
            }

        }
        // 上家出3不带
        else if (prevCardType == CardType.THREE_CARD) {
            // 3张牌可以大过上家的牌
            for (int i = mySize - 1; i >= 2; i--) {
                int grade0 = myCards.get(i);
                int grade1 = myCards.get(i - 1);
                int grade2 = myCards.get(i - 2);

                if (grade0 == grade1 && grade0 == grade2) {
                    if (grade0 > prevGrade) {
                        // 只要3张牌可以大过上家，则返回true
                        return true;
                    }
                }
            }

        }
        // 上家出3带1
        else if (prevCardType == CardType.THREE_ONE_CARD) {
            // 3带1 3不带 比较只多了一个判断条件
            if (mySize < 4) {
                return false;
            }

            // 3张牌可以大过上家的牌
            for (int i = mySize - 1; i >= 2; i--) {
                int grade0 = myCards.get(i);
                int grade1 = myCards.get(i - 1);
                int grade2 = myCards.get(i - 2);

                if (grade0 == grade1 && grade0 == grade2) {
                    if (grade0 > prevGrade) {
                        // 只要3张牌可以大过上家，则返回true
                        return true;
                    }
                }
            }

        }
        // 上家出炸弹
        else if (prevCardType == CardType.KING_BOMB_CARD) {
            // 4张牌可以大过上家的牌
            for (int i = mySize - 1; i >= 3; i--) {
                int grade0 = myCards.get(i);
                int grade1 = myCards.get(i - 1);
                int grade2 = myCards.get(i - 2);
                int grade3 = myCards.get(i - 3);

                if (grade0 == grade1 && grade0 == grade2 && grade0 == grade3) {
                    if (grade0 > prevGrade) {
                        // 只要有4张牌可以大过上家，则返回true
                        return true;
                    }
                }
            }

        }
        // 上家出4带2
        else if (prevCardType == CardType.FOUR_TWO_CARD) {
            // 4张牌可以大过上家的牌
            for (int i = mySize - 1; i >= 3; i--) {
                int grade0 = myCards.get(i);
                int grade1 = myCards.get(i - 1);
                int grade2 = myCards.get(i - 2);
                int grade3 = myCards.get(i - 3);

                if (grade0 == grade1 && grade0 == grade2 && grade0 == grade3) {
                    // 只要有炸弹，则返回true
                    return true;
                }
            }
        }
        // 上家出顺子
        else if (prevCardType == CardType.LIAN_CARD) {
            if (mySize < prevSize) {
                return false;
            } else {
                for (int i = mySize - 1; i >= prevSize - 1; i--) {
                    List<Integer> cards = new ArrayList<>();
                    for (int j = 0; j < prevSize; j++) {
                        cards.add(myCards.get(i - j));
                    }

                    CardType myCardType = GetCardType(cards);
                    if (myCardType == CardType.LIAN_CARD) {
                        int myGrade2 = cards.get(cards.size() - 1); // 最大的牌在最后
                        int prevGrade2 = prevCards.get(prevSize - 1);// 最大的牌在最后)
                        if (myGrade2 > prevGrade2) {
                            return true;
                        }
                    }
                }
            }

        }
        // 上家出连对
        else if (prevCardType == CardType.LIAN_DUI_CARD) {
            if (mySize < prevSize) {
                return false;
            } else {
                for (int i = mySize - 1; i >= prevSize - 1; i--) {
                    List<Integer> cards = new ArrayList<>();
                    for (int j = 0; j < prevSize; j++) {
                        cards.add(myCards.get(i - j));
                    }

                    CardType myCardType = GetCardType(cards);
                    if (myCardType == CardType.LIAN_DUI_CARD) {
                        int myGrade2 = cards.get(cards.size() - 1); // 最大的牌在最后
                        int prevGrade2 = prevCards.get(prevSize - 1);// 最大的牌在最后)

                        if (myGrade2 > prevGrade2) {
                            return true;
                        }
                    }
                }
            }

        }
        // 上家出飞机
        else if (prevCardType == CardType.FEIJI_NO_CARD) {
            if (mySize < prevSize) {
                return false;
            } else {
                for (int i = mySize - 1; i >= prevSize - 1; i--) {
                    List<Integer> cards = new ArrayList<>();
                    for (int j = 0; j < prevSize; j++) {
                        cards.add(myCards.get(i - j));
                    }

                    CardType myCardType = GetCardType(cards);
                    if (myCardType == CardType.FEIJI_NO_CARD) {
                        int myGrade4 = cards.get(4);//
                        int prevGrade4 = prevCards.get(4);

                        if (myGrade4 > prevGrade4) {
                            return true;
                        }
                    }
                }
            }
        }

        // 默认不能出牌
        return false;
    }




    public static void SortCards(List<Integer> cards) {
        cards.sort((Integer o1, Integer o2) -> {
            if (o1 > o2) {
                return 1;
            } else if (o1 < o2) {
                return -1;
            } else {
                return 1;
            }
        });
    }

    private static boolean CompareGrade(int grade1, int grade2) {
        return grade1 > grade2;
    }



    /// <summary>
    /// 判断是否为王炸
    /// </summary>
    /// <param name="myCards"></param>
    /// <returns></returns>
    static boolean IsDuiWang(List<Integer> myCards) {
        //默认不为王炸
        boolean flag = false;
        if (myCards != null && myCards.size() == 2) {
            if ((myCards.get(0) + myCards.get(1)) == 29) {
                flag = true;
            }
        }
        return flag;
    }

    /// <summary>
    /// 判断是否为单牌
    /// </summary>
    /// <param name="myCards"></param>
    /// <returns></returns>
    static boolean IsDan(List<Integer> myCards) {
        // 默认不是单
        boolean flag = false;
        if (myCards != null && myCards.size() == 1) {
            flag = true;
        }
        return flag;
    }

    /// <summary>
    /// 判断是否为对子
    /// </summary>
    /// <param name="myCards"></param>
    /// <returns></returns>
    static boolean IsDuiZi(List<Integer> myCards) {
        // 默认不是对子
        boolean flag = false;

        if (myCards != null && myCards.size() == 2) {
            int grade0 = myCards.get(0);
            int grade1 = myCards.get(1);
            if (grade0 == grade1) {
                flag = true;
            }
        }
        return flag;
    }

    /// <summary>
    /// 判断是否为三带一
    /// 三带一，被带的牌在牌尾,返回0，被带的牌在牌首,返回3
    /// </summary>
    /// <param name="myCards"></param>
    /// <returns></returns>
    public static int IsSanDaiYi(List<Integer> myCards) {
        int flag = -1;
        // 默认不是3带1
        if (myCards != null && myCards.size() == 4) {
            // 对牌进行排序
            SortCards(myCards);

            int[] grades = new int[4];
            grades[0] = myCards.get(0);
            grades[1] = myCards.get(1);
            grades[2] = myCards.get(2);
            grades[3] = myCards.get(3);

            // 暂时认为炸弹不为3带1
            if ((grades[1] == grades[0]) && (grades[2] == grades[0])
                    && (grades[3] == grades[0])) {
                return -1;
            }
            // 3带1，被带的牌在牌头
            else if ((grades[1] == grades[0] && grades[2] == grades[0])) {
                return 0;
            }
            // 3带1，被带的牌在牌尾
            else if (grades[1] == grades[3] && grades[2] == grades[3]) {
                return 3;
            }
        }
        return flag;
    }

    /// <summary>
    /// 判断是否为三带二
    /// 被带的牌在牌头，返回0，被带的牌在牌尾，返回3
    /// </summary>
    /// <param name="myCards"></param>
    /// <returns></returns>
    public static int IsSanDaiEr(List<Integer> myCards) {
        int flag = -1;
        // 默认不是3带2
        if (myCards != null && myCards.size() == 5) {
            // 对牌进行排序
            SortCards(myCards);

            int[] grades = new int[5];
            grades[0] = myCards.get(0);
            grades[1] = myCards.get(1);
            grades[2] = myCards.get(2);
            grades[3] = myCards.get(3);
            grades[4] = myCards.get(4);

            // 3带2，被带的牌在牌头
            if ((grades[1] == grades[0] && grades[2] == grades[3] && grades[4] == grades[3])) {
                return 0;
            }
            // 3带，被带的牌在牌尾
            else if (grades[0] == grades[1] && grades[2] == grades[1] && grades[4] == grades[3]) {
                return 3;
            }
        }
        return flag;
    }

    /// <summary>
    /// 判断是否三不带
    /// </summary>
    /// <param name="myCards"></param>
    /// <returns></returns>
    public static boolean IsSanBuDai(List<Integer> myCards) {
        // 默认不是3不带
        boolean flag = false;

        if (myCards != null && myCards.size() == 3) {
            int[] grades = new int[3];
            grades[0] = myCards.get(0);
            grades[1] = myCards.get(1);
            grades[2] = myCards.get(2);
            if (grades[0] == grades[1] && grades[2] == grades[0]) {
                flag = true;
            }
        }
        return flag;
    }

    /// <summary>
    /// 判断是否为顺子
    /// </summary>
    /// <param name="myCards"></param>
    /// <returns></returns>
    public static boolean IsShunZi(List<Integer> myCards)

    {
        // 默认是顺子
        boolean flag = true;

        if (myCards != null) {
            int size = myCards.size();
            // 顺子牌的个数在5到12之间
            if (size < 5 || size > 12) {
                return false;
            }
            // 对牌进行排序
            SortCards(myCards);
            for (int n = 0; n < size - 1; n++) {
                int prev = myCards.get(n);
                int next = myCards.get(n + 1);
                // 小王、大王、2不能加入顺子
                if (prev == 13 || prev == 14 || prev == 15 || next == 13
                        || next == 14 || next == 15) {
                    flag = false;
                    //System.out.println("you da xiao wang 2     " + flag);
                    break;
                } else {
                    if (prev - next != -1) {
                        flag = false;
                        //System.out.println("mei lian xu     " + flag);
                        break;
                    }
                }
            }
        }
        return flag;
    }

    /// <summary>
    /// 判断是否为炸弹
    /// </summary>
    /// <param name="myCards"></param>
    /// <returns></returns>
    public static boolean IsZhaDan(List<Integer> myCards) {
        // 默认不是炸弹
        boolean flag = false;
        if (myCards != null && myCards.size() == 4) {
            int[] grades = new int[4];
            grades[0] = myCards.get(0);
            grades[1] = myCards.get(1);
            grades[2] = myCards.get(2);
            grades[3] = myCards.get(3);
            if ((grades[1] == grades[0]) && (grades[2] == grades[0])
                    && (grades[3] == grades[0])) {
                flag = true;
            }
        }
        return flag;
    }

    /// <summary>
    /// 判断是否为连对
    /// </summary>
    /// <param name="myCards"></param>
    /// <returns></returns>
    public static boolean IsLianDui(List<Integer> myCards) {
        // 默认是连对
        boolean flag = true;
        if (myCards == null) {
            flag = false;
            return flag;
        }

        int size = myCards.size();
        if (size < 6 || size % 2 != 0) {
            flag = false;
        } else {
            // 对牌进行排序
            SortCards(myCards);
            for (int i = 0; i < size; i = i + 2) {
                if (myCards.get(i) != myCards.get(i + 1)) {
                    flag = false;
                    break;
                }

                if (i < size - 2) {
                    if (myCards.get(i) - myCards.get(i + 2) != -1) {
                        flag = false;
                        break;
                    }
                }
            }
        }

        return flag;
    }

    /// <summary>
    /// 判断是否为飞机不带
    /// </summary>
    /// <param name="myCards"></param>
    /// <returns></returns>
    public static boolean IsFeiJiBuDai(List<Integer> myCards) {
        boolean flag = false;
        if (myCards != null && myCards.size() % 3 == 0) {
            CardTypeIndex carT_index = CardIndexCompute(myCards);
            if (carT_index.three_index.contains(13))  //飞机主体不能带2
            {
                return false;
            }

            SortCards(carT_index.three_index);
            for (int i = 0; i < carT_index.three_index.size() - 1; i++) //飞机的主体必须是连续的，如333 555就不行
            {
                if (carT_index.three_index.get(i + 1) - carT_index.three_index.get(i) != 1) {
                    return false;
                }
            }

            //飞机不带的模型是 4=0，3！=0，2=0，1=0
            if (carT_index.four_index.size() == 0 && carT_index.three_index.size() != 0 && carT_index.double_index.size() == 0 && carT_index.single_index.size() == 0) {
                flag = true;
            }
        }
        return flag;
    }

    /// <summary>
    /// 判断是否为飞机带单
    /// </summary>
    /// <param name="myCards"></param>
    /// <returns></returns>
    public static boolean IsFeiJiDaiDan(List<Integer> myCards) {
        boolean flag = false;
        if (myCards != null && myCards.size() % 4 == 0) {
            CardTypeIndex carT_index = CardIndexCompute(myCards);
            if (carT_index.three_index.contains(13))  //飞机主体不能带2
            {
                return false;
            }

            SortCards(carT_index.three_index);
            for (int i = 0; i < carT_index.three_index.size() - 1; i++) //飞机的主体必须是连续的，如333 555就不行
            {
                if (carT_index.three_index.get(i + 1) - carT_index.three_index.get(i) != 1) {
                    return false;
                }
            }

            //飞机带单的模型是 4=0，3！=0，2*2 + 1 = 主体数（即比如 333 444 555 可以带 667 678）
            if (carT_index.four_index.size() == 0 && carT_index.three_index.size() != 0) {
                if (carT_index.double_index.size() * 2 + carT_index.single_index.size() == carT_index.three_index.size())
                    flag = true;
            }
        }
        return flag;
    }

    /// <summary>
    /// 判断是否为飞机带对
    /// </summary>
    /// <param name="myCards"></param>
    /// <returns></returns>
    public static boolean IsFeiJiDaiDui(List<Integer> myCards) {
        boolean flag = false;
        if (myCards != null && myCards.size() % 5 == 0) {
            CardTypeIndex carT_index = CardIndexCompute(myCards);
            if (carT_index.three_index.contains(13))  //飞机主体不能带2
            {
                return false;
            }

            SortCards(carT_index.three_index);
            for (int i = 0; i < carT_index.three_index.size() - 1; i++) //飞机的主体必须是连续的，如333 555就不行
            {
                if (carT_index.three_index.get(i + 1) - carT_index.three_index.get(i) != 1) {
                    return false;
                }
            }

            //飞机带对的模型是 4=0，3！=0，2！=0且 2=3, 1 = 0

            if (carT_index.four_index.size() == 0 && carT_index.three_index.size() != 0) {
                if (carT_index.double_index.size() == carT_index.three_index.size() && carT_index.single_index.size() == 0)
                    flag = true;
            }
        }
        return flag;
    }

    /// <summary>
    /// 判断是否为四带二
    /// </summary>
    /// <param name="myCards"></param>
    /// <returns></returns>
    public static boolean IsSiDaiEr(List<Integer> myCards) {
        boolean flag = false;
        if (myCards != null && myCards.size() == 6) {
            CardTypeIndex carT_index = CardIndexCompute(myCards);
            if (carT_index.four_index.size() == 1 && carT_index.three_index.size() == 0) {
                if (carT_index.single_index.size() == 2 || carT_index.double_index.size() == 1) {
                    flag = true;
                }
            }
        }
        return flag;
    }

    /// <summary>
    /// 判断是否为四带二对
    /// </summary>
    /// <param name="myCards"></param>
    /// <returns></returns>
    public static boolean IsSiDaiErDui(List<Integer> myCards) {
        boolean flag = false;
        if (myCards != null && myCards.size() == 8) {
            CardTypeIndex carT_index = CardIndexCompute(myCards);
            if (carT_index.four_index.size() == 1 && carT_index.three_index.size() == 0) {
                if (carT_index.double_index.size() == 2) {
                    flag = true;
                }
            }
        }
        return flag;
    }

    //计算牌中的4，3，2，1个数
    public static CardTypeIndex CardIndexCompute(List<Integer> mycards) {
        CardTypeIndex cardT_index = new CardTypeIndex();
        cardT_index.single_index = new ArrayList<>();
        cardT_index.double_index = new ArrayList<>();
        cardT_index.three_index = new ArrayList<>();
        cardT_index.four_index = new ArrayList<>();
        List<Integer> pre = new ArrayList<>();
        for (int i = 0; i < mycards.size(); i++) {
            pre.add(mycards.get(i));
        }
        //重写算法 对牌进行分类
        //15种牌
        int[] record = new int[]{0, 0, 0, 0, 0,
                0, 0, 0, 0, 0,
                0, 0, 0, 0, 0};
        for (Integer i : pre)
            record[i + 1] = record[i + 1] + 1;  //    计数器加1

        for (int i = 0; i < 15; i++) {
            if (record[i] == 1)
                cardT_index.single_index.add(i);
            if (record[i] == 2)
                cardT_index.double_index.add(i);
            if (record[i] == 3)
                cardT_index.three_index.add(i);
            if (record[i] == 4)
                cardT_index.four_index.add(i);
        }
        return cardT_index;
    }


}
